//
// Created by francklinson on 2021/7/25 AT 11:09.
//
/*
如果出现下述两种情况，交易 可能无效：

交易金额超过 ¥1000
或者，它和另一个城市中同名的另一笔交易相隔不超过 60 分钟（包含 60 分钟整）
每个交易字符串transactions[i]由一些用逗号分隔的值组成，这些值分别表示交易的名称，时间（以分钟计），金额以及城市。

给你一份交易清单transactions，返回可能无效的交易列表。你可以按任何顺序返回答案。
*/

#include <string>
#include <iostream>
#include <vector>
#include <tuple>
#include <unordered_map>
#include <sstream>
#include <unordered_set>

using namespace std;


class Transaction {
public:

    string name; // 用户名
    int time;
    int amount;
    string city;
    int id;      // 交易号
    string full; // 原始字符串

    Transaction(string infoString, int id) : id(id) {
        infoExtraction(infoString);
        full = infoString;
    }

    /**
    * 提取 交易名称  时间  金额  地点信息
    * @param infoString
    * @return
    */
    void infoExtraction(string infoString) {
        vector<string> res;
        stringstream ss(infoString);
        string curr;
        while (std::getline(ss, curr, ',')) {
            res.push_back(curr);
        }
        name = res[0];
        time = stoi(res[1]);
        amount = stoi(res[2]);
        city = res[3];
    }
};

class Solution {
private:


public:
    vector<string> invalidTransactions(vector<string> &transactions) {
        // 映射表
        unordered_map<string, vector<Transaction>> name2transactions;
        // 返回结果
        vector<string> ans;
        // 记录是否已经输出
        unordered_set<int> seen;
        for (int i = 0; i < transactions.size(); ++i) {
            auto x = Transaction(transactions[i], i);
            if (x.amount > 1000) {
                ans.push_back(transactions[i]);
                seen.insert(i);
            }
            for (auto &t:name2transactions[x.name]) {
                // 找到不符合条件的
                if (abs(t.time - x.time) <= 60 and t.city != x.city) {
                    if (!seen.count(t.id)) {
                        seen.insert(t.id);
                        ans.push_back(t.full);
                    }
                    if (!seen.count(x.id)) {
                        seen.insert(x.id);
                        ans.push_back(transactions[i]);
                    }
                }
            }
            name2transactions[x.name].push_back(x);
        }
        return ans;
    }


};

int main() {
    vector<string> transactions{"bob,689,1910,barcelona", "alex,696,122,bangkok", "bob,832,1726,barcelona",
                                "bob,820,596,bangkok",
                                "chalicefy,217,669,barcelona", "bob,175,221,amsterdam"};
    Solution solution;
    auto ans = solution.invalidTransactions(transactions);
    for (auto &x:ans) cout << x << endl;
    return 0;
}

